<template>
  <div ref="p5Container"></div>
</template>

<script>
import p5 from 'p5';

export default {
  name: 'Fireworks',
  data() {
    return {
      sketch: null
    };
  },
  mounted() {
    this.sketch = new p5(this.p5Sketch, this.$refs.p5Container);
  },
  beforeDestroy() {
    if (this.sketch) {
      this.sketch.remove();
    }
  },
  methods: {
    p5Sketch(p) {
      let fireworks = [];
      let gravity;
      const words = [
        '变美',
        '快乐',
        '发财',
        '暴富',
        '爱情',
        '桃花',
        '幸福',
        '健康',
        '进步',
        '好运',
        '必过',
        '平安',
        '升职',
        '和睦',
        '涨薪',
        '脱单'
      ];

      class Particle {
        constructor(x, y, hu, firework) {
          this.pos = p.createVector(x, y);
          this.firework = firework;
          this.lifespan = 255;
          this.hu = hu;
          this.bless = null;
          if (this.firework) {
            if (p.windowHeight < 640) {
              this.vel = p.createVector(0, p.random(-16, -13));
            } else {
              this.vel = p.createVector(0, p.random(-17, -15));
            }
          } else {
            this.vel = p.createVector(p.random(-1, 1), p.random(-1, 1));
            this.vel.mult(p.random(2, 30));
            if (p.random(1) < 0.01) {
              this.bless = new Blessing(this.pos, this.hu);
            }
          }
          this.acc = p.createVector(0, 0);
        }

        applyForce(force) {
          this.acc.add(force);
        }

        update() {
          if (!this.firework) {
            this.vel.mult(0.9);
            this.lifespan -= 4;
          }
          this.vel.add(this.acc);
          this.pos.add(this.vel);
          this.acc.mult(0);
        }

        done() {
          return this.lifespan < 0;
        }

        show(p) {
          p.colorMode(p.HSB);
          if (!this.firework) {
            p.strokeWeight(2);
            p.stroke(this.hu, 255, 255, this.lifespan);
            if (this.bless) {
              this.bless.show(p); // 传递 p
            }
          } else {
            p.strokeWeight(4);
            p.stroke(this.hu, 255, 255);
          }
          p.point(this.pos.x, this.pos.y);
        }
      }

      class Firework {
        constructor() {
          this.hu = p.random(255);
          this.firework = new Particle(p.random(p.width), p.height, this.hu, true);
          this.exploded = false;
          this.particles = [];
        }

        done() {
          return this.exploded && this.particles.length === 0;
        }

        update() {
          if (!this.exploded) {
            this.firework.applyForce(gravity);
            this.firework.update();
            if (this.firework.vel.y >= 0) {
              this.exploded = true;
              this.explode();
            }
          }
          for (let i = this.particles.length - 1; i >= 0; i--) {
            this.particles[i].applyForce(gravity);
            this.particles[i].update();
            if (this.particles[i].done()) {
              this.particles.splice(i, 1);
            }
          }
        }

        explode() {
          for (let i = 0; i < 100; i++) {
            const p = new Particle(this.firework.pos.x, this.firework.pos.y, this.hu, false);
            this.particles.push(p);
          }
        }

        show(p) {
          if (!this.exploded) {
            this.firework.show(p); // 传递 p
          }
          for (let i = 0; i < this.particles.length; i++) {
            this.particles[i].show(p); // 传递 p
          }
        }
      }

      class Blessing {
        constructor(pos, hu) {
          this.pos = pos.copy();
          this.hu = hu;
          this.content = words[p.floor(p.random() * words.length)];
        }

        show(p) {
          p.stroke(255);
          p.fill(this.hu, 255, 255);
          p.textFont('华文彩云');
          p.textStyle('bold');
          p.textSize(20);
          p.text(this.content, this.pos.x, this.pos.y);
        }
      }

      p.setup = () => {
        p.createCanvas(p.windowWidth, p.windowHeight);
        p.colorMode(p.HSB);
        gravity = p.createVector(0, 0.2);
        p.stroke(255);
        p.strokeWeight(4);
      };

      p.draw = () => {
        p.colorMode(p.RGB);
        p.background(0, 0, 0, 25); // 设置带有透明度的背景
        if (p.random(1) < 0.2) {
          fireworks.push(new Firework());
        }
        for (let i = fireworks.length - 1; i >= 0; i--) {
          fireworks[i].update();
          fireworks[i].show(p); // 传递 p
          if (fireworks[i].done()) {
            fireworks.splice(i, 1);
          }
        }
      };
    }
  }
};
</script>

<style scoped>
/* 在这里编写你的组件样式 */
div {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  overflow: hidden;
  pointer-events: none;
  background: transparent; /* 设置透明背景 */
}
</style>
